#pragma once
#include "EventLoop.hpp"
#include "Buffer.hpp"
#include "Channel.hpp"
#include "HttpRequest.hpp"
#include "Httpresponse.hpp"

#include <stdlib.h>
#include <stdio.h>
// #define MSG_SEND_AUTO
class TcpConnetion
{
public:
    TcpConnetion(int fd, EventLoop *evloop)
    {
        m_evLoop = evloop;
        m_readBuf = new Buffer(10240);
        m_writeBuf = new Buffer(10240);
        m_request = new HttpRequest;
        m_response = new HttpResponse;
        m_name = "Connection-" + to_string(fd);
        m_channel = new Channel(fd, FDEvent::ReadEvent, processRead, processWrite, Destory, this);
        evloop->addTask(m_channel, ElemType::ADD);
    }
    ~TcpConnetion()
    {
        if (m_readBuf && m_readBuf->readableSize() == 0 &&
            m_writeBuf && m_writeBuf->readableSize() == 0)
        {
            delete m_readBuf;
            delete m_writeBuf;
            delete m_request;
            delete m_response;
            m_evLoop->freeChannel(m_channel);
        }
    }

    static int processRead(void *arg)
    {
        TcpConnetion *conn = static_cast<TcpConnetion *>(arg);
        // 接收数据
        int socket = conn->m_channel->getSocket();
        // int count =conn->m_readBuf->socketRead(socket);
        int count = conn->m_readBuf->socktRead(conn->m_channel->getSocket());
        if (count > 0)
        {
            // 接收到了Http请求，解析http请求

#ifdef MSG_SEND_AUTO
            m_channel->writeEventEnable(true);
           // conn->m_channel->writeEventEnable(true);
            conn->m_evLoop->addTask(conn->m_channel, ElemType::MODIFY);

#endif
            bool flag = conn->m_request->parseHttpRequest(conn->m_readBuf, conn->m_response, conn->m_writeBuf, socket);
            if (!flag)
            {
                // 解析失败，回复一个html
                string errMsg = "Http/1.1 400 Bad Request\r\n\r\n";
                conn->m_writeBuf->appendString(errMsg);
            }
        }
        else
        {
#ifndef MSG_SEND_AUTO
            // 断开连接
            conn->m_evLoop->addTask(conn->m_channel, ElemType::DELETE);

#endif
        }
#ifndef MSG_SEND_AUTO
        // 断开连接
        conn->m_evLoop->addTask(conn->m_channel, ElemType::DELETE);
#endif
        return 0;
    }
    static int processWrite(void *arg)
    {
        TcpConnetion *conn = static_cast<TcpConnetion *>(arg);
        // 发送数据
        int count = conn->m_writeBuf->sendData(conn->m_channel->getSocket());
        if (count > 0)
        {
            // 判断数据是否被全部发送出去
            if (conn->m_writeBuf->readableSize() == 0)
            {
                // 1.不再检测写事件 --修改channel中保存的事件
                conn->m_channel->writEventEnbale(false); // 不检测，第二个参数填false
                                                         // 2.修改dispatcher检测的集合 --添加任务节点
                conn->m_evLoop->addTask(conn->m_channel, ElemType::MODIFY);

                // 3.删除节点
                conn->m_evLoop->addTask(conn->m_channel, ElemType::DELETE);
            }
        }
    }
    static int TcpConnetion::Destory(void *arg)
    {
        TcpConnetion *conn = static_cast<TcpConnetion *>(arg);
        if (conn != nullptr)
        {
            delete conn;
        }
        return 0;
    }

private:
    class EventLoop *m_evLoop;
    Channel *m_channel;
    Buffer *m_readBuf;
    Buffer *m_writeBuf;
    string m_name;
    // http协议
    HttpRequest *m_request;
    HttpResponse *m_response;
};